package jmine.tec.web.servlet;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import jmine.tec.web.servlet.util.WebSpringHelper;

import org.springframework.beans.factory.BeanFactory;

/**
 * ServletFilter base para filtros que precisem acessar a BeanFactory. Para funcionar corretamente a aplicação deve ser inicializada pelo
 * {@link InitServletContextListener} ou algum servlet derivado.
 * 
 * @created May 5, 2008
 * @author Gustavo Almeida
 */
public abstract class BeanFactoryServletFilter implements Filter {
    private BeanFactory beanFactory;

    private ServletContext servletContext;

    /**
     * Chamado para inicializar o filtro.
     * 
     * @param filterConfig config do filtro.
     * @throws ServletException se o {@link BeanFactoryServletFilter#initialize(FilterConfig)} lançar a mesma exceção.
     */
    public final void init(FilterConfig filterConfig) throws ServletException {
        this.servletContext = filterConfig.getServletContext();
        this.initialize(filterConfig);
    }

    /**
     * Chamado pelo {@link BeanFactoryServletFilter#init(FilterConfig)} para inicializar o filtro.
     * 
     * @param filterConfig config do filtro
     * @throws ServletException em caso de erro.
     * @see {@link Filter#init(FilterConfig)}
     */
    public abstract void initialize(FilterConfig filterConfig) throws ServletException;

    /**
     * Devolve a BeanFactory.
     * 
     * @return bean factory
     */
    protected BeanFactory getBeanFactory() {
        if (this.beanFactory == null) {
            this.beanFactory = WebSpringHelper.getBeanFactory(this.servletContext);
        }
        return this.beanFactory;
    }

    /**
     * Devolve um bean, recuperando-o pela beanfactory.
     * 
     * @param <T> tipo do bean.
     * @param name nome do bean.
     * @param clazz tipo do bean.
     * @return bean.
     */
    @SuppressWarnings("unchecked")
    protected <T> T getBean(String name, Class<T> clazz) {
        return (T) this.getBeanFactory().getBean(name);
    }

    /**
     * Devolve o valor do parametro ou o valor default caso o parametro nao tenha sido definido.
     * 
     * @param filterConfig configuração do filtro.
     * @param paramName chave do parâmetro.
     * @param defaultValue valor default.
     * @return o valor da propriedade ou <code>defaultValue</code> se a propriedade não estiver definida.
     */
    protected String getParameter(FilterConfig filterConfig, String paramName, String defaultValue) {
        String value = filterConfig.getInitParameter(paramName);
        return (value != null) ? value : defaultValue;
    }
}